// mod_imglib.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "../hencvik_api.h"
#include "resource.h"
#include "autobuild.h"
#include <stdlib.h>
#include <commdlg.h>
#include "utstrings.h"
#include "zmessages.h"
#include "zibuffer.h"
#include "zimage.h"


HINSTANCE g_hInstance;
plugin_link *link;

hencvik_plugin_info plugin_info =
{
	HCK_DRIVER,
	"mod_imglib",
	__BUILD__,
	"Image library (build "__BUILD_STR__")",
	"Provide support for some image formats\r\nCompiled at "__DATE__" "__TIME__,
	"pf_ziminski (c) 2009",
	"pfzim@mail.ru",
	"http://www.pfzim.ru/",
	"http://www.pfzim.ru/update.php?app=mod_imglib&ver="__BUILD_STR__,
	{ 0x21ceaedf, 0xda37, 0x45d6, { 0xac, 0xfe, 0xb4, 0xfe, 0x9b, 0xaf, 0xf4, 0x6e } }	// {21CEAEDF-DA37-45d6-ACFE-B4FE9BAFF46E}
};

BOOL CALLBACK DialogProc_Options(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
		case WM_INITDIALOG:
			{
				/*
				char *temp_str;
				HBITMAP hbmImage;

				temp_str = alloc_string((char *) link->call("config/path", NULL, NULL));
				alloc_strcat(&temp_str, "test.jpg");
				if(link->call("image/load/file", temp_str, &hbmImage) == HR_OK)
				{
					SendDlgItemMessage(hwnd, IDC_PICTURE, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hbmImage);
					//DeleteObject(hbmImage);
				}
				*/

				link->call("langpack/translate_window", hwnd, NULL);
			}
			return TRUE;
/*
		case WM_COMMAND:
			switch(LOWORD(wParam))
			{
				case IDC_USEPROXY:
				case IDC_USENTLM:
					SendMessage(GetParent(hwnd), PSM_CHANGED, (WPARAM) hwnd, 0L);
					break;
				case IDC_SERVER:
				case IDC_PORT:
				case IDC_LOGIN:
				case IDC_PASSWD:
					if(HIWORD(wParam) == EN_CHANGE)
					{
						SendMessage(GetParent(hwnd), PSM_CHANGED, (WPARAM) hwnd, 0L);
					}
				break;
			}
			break;
*/
		case WM_NOTIFY:
			{
				switch(((NMHDR*) lParam)->code)
				{
					case PSN_APPLY:
						{
							/*
							char *temp_str;
							char *temp_str2;
							unsigned long flags;

							flags = (SendDlgItemMessage(hwnd, IDC_USEPROXY, BM_GETCHECK, 0, 0L) == BST_CHECKED)?NLO_USEPROXY:0;
							flags |= (SendDlgItemMessage(hwnd, IDC_USENTLM, BM_GETCHECK, 0, 0L) == BST_CHECKED)?NLO_USENTLM:0;
							
							link->call("config/set/long", "proxy_enable", pv(flags));

							temp_str = AllocGetDlgItemText(hwnd, IDC_SERVER);
							link->call("config/set/string", "proxy_host", temp_str);
							free_str(temp_str);

							temp_str = AllocGetDlgItemText(hwnd, IDC_PORT);
							link->call("config/set/string", "proxy_port", temp_str);
							free_str(temp_str);
							
							temp_str = AllocGetDlgItemText(hwnd, IDC_LOGIN);
							link->call("config/set/string", "proxy_user", temp_str);
							free_str(temp_str);

							temp_str = AllocGetDlgItemText(hwnd, IDC_PASSWD);
							temp_str2 = (char *) alloc_en64((const unsigned char *) temp_str, strlen(temp_str));
							link->call("config/set/string", "proxy_passwd", temp_str2);
							free_str(temp_str2);
							free_str(temp_str);
							//link->call("service/message", "db_mysql (build "__BUILD_STR__"): information", "Settings was applyed after restart application!");
							*/

							SetWindowLong(hwnd, DWL_MSGRESULT, PSNRET_NOERROR);
						}
						return TRUE;
				}
			}
			break;
	}
	return FALSE;
}

// cmd		- "image/load/mem"
// param1[0]- (char *) in_buffer
// param1[1]- (unsigned long) size
// param2	- (char **) out_buffer
// return:	HR_OK or HR_ERROR
void *image_load_mem(char *cmd, void *param1, void *param2)
{
	HBITMAP hbmImage;
	unsigned long w, h;
	unsigned long bytes_per_line;
	unsigned char *bits;

	*(void **) param2 = NULL;

	bits = zimage_load_jpeg((const unsigned char *) ((void **) param1)[0], (unsigned long) ((void **) param1)[1], &w, &h, &bytes_per_line);
	if(bits)
	{
		BITMAPINFO bmi;

		bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		bmi.bmiHeader.biWidth = w;
		bmi.bmiHeader.biHeight = h;
		bmi.bmiHeader.biPlanes = 1;
		bmi.bmiHeader.biBitCount = 32;
		bmi.bmiHeader.biCompression = BI_RGB;
		bmi.bmiHeader.biSizeImage = 0;
		bmi.bmiHeader.biXPelsPerMeter = 0;
		bmi.bmiHeader.biYPelsPerMeter = 0;
		bmi.bmiHeader.biClrUsed = 0;
		bmi.bmiHeader.biClrImportant = 0;

		HDC hdc = GetDC(NULL);
		hbmImage = CreateCompatibleBitmap(hdc, w, h);
		SetDIBits(NULL, hbmImage, 0, h, bits, &bmi, DIB_RGB_COLORS);
		ReleaseDC(NULL, hdc);
		zfree(bits);

		if(hbmImage)
		{
			*(void **) param2 = pv(hbmImage);
			return HR_OK;
		}
	}

	return HR_ERROR;
}

// cmd		- "image/load/file"
// param1	- (char *) path
// param2	- (char **) buffer
// return:	HR_OK or HR_ERROR
void *image_load_file(char *cmd, void *param1, void *param2)
{
	EXTBUFFER zb;
	char *data;
	HBITMAP hbmImage;
	unsigned long w, h;
	unsigned long bytes_per_line;
	unsigned char *bits;

	unsigned long size;

	*(void **) param2 = NULL;

	if(__initbufferedread((char *) param1, &zb, 32768))
	{
		data = __alloc_getblock(&zb, 0, zb.dwFileSize);
		size = zb.dwFileSize;
		__destructbufferedreadwrite(&zb);

		bits = zimage_load_jpeg((const unsigned char *) data, size, &w, &h, &bytes_per_line);
		zfree(data);
		if(bits)
		{
			BITMAPINFO bmi;

			bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
			bmi.bmiHeader.biWidth = w;
			bmi.bmiHeader.biHeight = h;
			bmi.bmiHeader.biPlanes = 1;
			bmi.bmiHeader.biBitCount = 32;
			bmi.bmiHeader.biCompression = BI_RGB;
			bmi.bmiHeader.biSizeImage = 0;
			bmi.bmiHeader.biXPelsPerMeter = 0;
			bmi.bmiHeader.biYPelsPerMeter = 0;
			bmi.bmiHeader.biClrUsed = 0;
			bmi.bmiHeader.biClrImportant = 0;

			HDC hdc = GetDC(NULL);
			hbmImage = CreateCompatibleBitmap(hdc, w, h);
			SetDIBits(NULL, hbmImage, 0, h, bits, &bmi, DIB_RGB_COLORS);
			ReleaseDC(NULL, hdc);
			zfree(bits);

			if(hbmImage)
			{
				*(void **) param2 = pv(hbmImage);
				return HR_OK;
			}
		}
	}

	return HR_ERROR;
}

// cmd		- "image/free"
// param1	- (HBITMAP) hBitmap
// param2	- NULL
// return:	HR_OK or HR_ERROR
void *image_free(char *cmd, void *param1, void *param2)
{
	if(DeleteObject(param1))
	{
		return HR_OK;
	}

	return HR_ERROR;
}

void *onconfig(char *cmd, hencvik_page_info *page_info, void *param2)
{
	strncpy_tiny(page_info->group, $("Services"), 49);
	strncpy_tiny(page_info->name, $("Images"), 49);
	page_info->handle = g_hInstance;
	page_info->resource = MAKEINTRESOURCE(IDD_OPTIONS);
	page_info->proc = DialogProc_Options;

	return HR_OK;
}

extern "C" __declspec(dllexport) hencvik_plugin_info *HencvikPluginInfo(unsigned long build)
{
	return &plugin_info;
}

extern "C" __declspec(dllexport) int Load(plugin_link *plink)
{
	link = plink;

	//link->call("notify/register", "global/events/configshow", onconfig);

	link->call("service/register", "image/load/file", image_load_file);
	link->call("service/register", "image/load/mem", image_load_mem);
	link->call("service/register", "image/free", image_free);

	return LR_OK;
}

extern "C" __declspec(dllexport) int Unload(void)
{
	//link->call("notify/unregister", "global/events/configshow", onconfig);

	link->call("service/unregister", "image/load/file", NULL);
	link->call("service/unregister", "image/load/mem", NULL);
	link->call("service/unregister", "image/free", NULL);

	return 0;
}

extern "C" BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
	g_hInstance = (HINSTANCE) hModule;

    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }

    return TRUE;
}

